#coding=utf-8
'''
Created on 2015年5月27日
'''

import tornado
from tornado import gen
from util_base.exception import UFOException, UnhandledException, NotImplementedException
from util_base.protocol import ResponseBuilder
from common_base.errors import AliveError
from setting_base import setting
from concurrent.futures.thread import ThreadPoolExecutor
from tornado.concurrent import run_on_executor




class BaseHandler(tornado.web.RequestHandler):
    '''
    base handler, define common flow of request processing
    '''
    
    executor = ThreadPoolExecutor(10)
    
    def __init__(self, *args, **kwargs):
        '''
        Constructor
        '''
        
        super(BaseHandler, self).__init__(*args, **kwargs)
        
        self.cmdid = 0
        self.timestamp = 0
        self.userid = ""
        self.userkey = ""
        self.version = ""
        self.platform = 0
        self.release = 0
        self.geo = ""
        self.params = dict()
        self.common = dict()
        
        self._process_cls = None
        #self._processor = None
        self.template_name = ''
        self.res = dict()
        self._data = None
        
        
        self.path = self.request.uri.split('?')[0].rstrip('/')
        
        self.tracker = None
        self.sys_logger = None
    
    @tornado.web.asynchronous
    @gen.coroutine    
    def get(self):
        '''
        GET
        '''
        self.finish()
        
    @tornado.web.asynchronous
    @gen.coroutine
    def post(self): 
        '''
        POST
        '''
        
        try:
            # 记录请求
            self.tracker.logging_request_header(self)
            
            # 解析请求头(子类实现)
            self.parse_header()
            
            # 解析请求体(子类实现)
            try:
                parsed_body = self.parse_body()
            except:
                # 记录请求体
                self.tracker.logging_request_body(self, text=self.request.body)
                raise
            else:
                # 记录请求体
                self.tracker.logging_request_body(self, parsed_body)
            
            # 分发processor
            processor_meta = getattr(setting, 'processor_mapping').get(self.cmdid)
            if not processor_meta:
                # 协议不存在
                raise UFOException(AliveError.ERROR_COMMON_CMD_NOT_EXISTS)
            
            # 校验processor_meta(子类实现)
            self.verify_processor_meta(processor_meta)
            
            # 实例化processor
            self._process_cls = processor_meta.cls
            
            
            data = yield self._do_process()
            
            
            # 成功
            self.res = ResponseBuilder.build_success(self, data)
        except UFOException as e:
            # 根据捕获的UFOException返回错误信息
            self.res = ResponseBuilder.build_error(self, e)
        except UnhandledException as e:
            # 如果是底层未处理的Exception, 在这里记录日志后转化为UFOException
            self.tracker.trace_error()
            self.res = ResponseBuilder.build_error(self, UFOException(e.code, **e.ext))
        except Exception as e:
            self.tracker.trace_error()
            e = UFOException(AliveError.ERROR_COMMON_UNKNOWN)
            self.res = ResponseBuilder.build_error(self, e)
        
        try:
            # 序列化响应(子类实现)
            serialized_res = self.serialize_response()
            self.tracker.logging_response(self, self.res)
            # 响应
            self.write(serialized_res)
            self.finish()

        except:
            self.tracker.trace_error()
            raise
        finally:
            self.tracker.flush()
            
    
    @run_on_executor(executor='executor')
    def _do_process(self):
        
        _processor = self._process_cls(self)
        try:
            _processor.get_connections()
            _processor._verify_params()
            data = _processor.process()
        except:
            raise
        finally:
            _processor.return_connections()
        return data
        
    def parse_header(self):
        '''
        to be override
        '''
        
        raise NotImplementedException()
    
    def parse_body(self):
        '''
        to be override
        '''
        
        raise NotImplementedException()
    
    def verify_processor_meta(self):
        '''
        to be override
        '''
        
        
    def serialize_response(self):
        '''
        to be override
        '''
        
        raise NotImplementedException
        
    

